package testEnvironment;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;

import com.agentfactory.teleoreactive.interpreter.mentalstate.AbstractComponent;

public class BlocksWorld extends AbstractComponent {
	private static BlocksWorld t = new BlocksWorld(7);
	private HashMap<String, Boolean> onMap;
	private ArrayList<String> blocks;
	private String holding;
	
	public static BlocksWorld getIntance(){return t;}
	
	public BlocksWorld(int i){
		blocks = new ArrayList<String>();
		/** Add the Blocks to the Environment. */
		for (Char c : Char.values()) {
			if(c.ordinal() < i)
				blocks.add(c.toString());
		}
		onMap = new HashMap<String, Boolean>();
		/** Make sure no block is on any other. */
		for (String on : blocks) {
				onMap.put(on+",Table", new Boolean(true));
			for (String under : blocks) {
				onMap.put(on+","+under, new Boolean(false));
			}
		}
		/** We are not holding anything */
		holding = "";
	}
	
	public List<String> percieve(){
		List<String> ret = new LinkedList<String>();
		for (String key : onMap.keySet()) {
			if(onMap.get(key)) {
				ret.add("isOn("+key+")");
			}
		}
		if(holding != "")
			ret.add("holding("+holding+")");
		return ret;
	}
	
	public boolean pickUp(String cha){
		//System.out.println("Picking up "+cha);
		if(holding != "") return false; // check were not holding anything
		for (String key : onMap.keySet()) {// check block is clear
			if(key.endsWith(cha))
				if(onMap.get(key))
					return false;
		}
		holding = cha;
		for (String key : onMap.keySet()) {// check block is clear
			if(key.startsWith(cha))
				if(onMap.get(key))
					onMap.put(key, new Boolean(false));
		}
		
		return true;
		
	}
	
	/**
	 * @param place "Table" or the block on which we want to place the block we are holding.
	 * @throws InvalidOperationException this occurs when place is not clear or we aren't holding anything.
	 * */
	public boolean place(String place){
		if(place.equals("Table")){
			onMap.put(holding+",Table", new Boolean(true));
			holding = "";
			return true;
		}else {
			if(holding.equals("")) return false; // check we're holding a block
			for (String key : onMap.keySet()) {// check destination block is clear
				if(key.endsWith(place)){
					if(onMap.get(key)){
						return false;
					}
				}
			}
			onMap.put(holding+","+place, new Boolean(true));
			holding = "";
			return true;
		}
	}

}
